#include "StdAfx.h"
#include "Trigger.h"


Trigger::Trigger(void)
{
	//countOfReqs = 0;
	countOfAccceptedReqs = 0;
	deleted = false;
	allReqDirty = false;
	dirty = true;
}


Trigger::~Trigger(void)
{
}

//Checks the requirements fot the trigger
bool Trigger::CheckReq(EntityControl *entity)
{
	dirty = false;

	if(TriggerRequirements.empty())
		return true;
	
	if(allReqDirty)
	{
		//bool ret = false;
		for(std::vector<TriggerRequirement*>::iterator i = TriggerRequirements.begin(); i!=TriggerRequirements.end();i++)
		{
			if(!(*i)->CheckReq(entity))
				return false;
		}
		return true;


	}
	else
	{



		for(std::vector<TriggerRequirement*>::iterator i = dirtyTriggerRequirements.begin(); i!=dirtyTriggerRequirements.end();i++)
		{
			if(!(*i)->CheckReq(entity))
			{
				if((*i)->getPrevResult())
				{
					countOfAccceptedReqs--;
					(*i)->setResult(false);
				}
			}
			else
			{
				if(!(*i)->getPrevResult())
				{
					countOfAccceptedReqs++;
					(*i)->setResult(true);
				}
			}

		}

		dirtyTriggerRequirements.clear();

		if(countOfAccceptedReqs>= TriggerRequirements.size())
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
}



//Fires the trigger
bool Trigger::FireTrigger(EntityControl *entity)
{

	bool ret = false;
	for(std::vector<TriggerAction*>::iterator i = TriggerActions.begin(); i!=TriggerActions.end();i++)
	{
		if((*i)->FireTrigger(entity))
			ret = true;
	}

	return ret;
}


bool Trigger::UseTrigger(EntityControl *entity)
{
	bool res = CheckReq(entity);
	if(!res)
		return false;
	res = FireTrigger(entity);
	return res;
}

void Trigger::addRequiement(TriggerRequirement* req)
{

	req->setOwnerTrigger(this);
	dirtyTriggerRequirements.push_back(req);
	TriggerRequirements.push_back(req);
}

void Trigger::addAction(TriggerAction* action)
{
	TriggerActions.push_back(action);
}

void Trigger::setDirty(EntityControl *sourceEntity,TriggerRequirement *dirtyReq)
{
	
	if(!allReqDirty)
	{
		dirtyTriggerRequirements.push_back(dirtyReq);
	}
	
	if(!dirty)
	{
		dirty=true;
		sourceEntity->setTriggerDirty(this);
	}
}


void Trigger::setDirty(EntityControl *sourceEntity)
{
	if(!dirty)
	{
		dirty=true;
		sourceEntity->setTriggerDirty(this);
	}
}

void Trigger::subscribeParameterChanged(EntityControl *entity)
{


	for(std::vector<TriggerRequirement*>::iterator i = TriggerRequirements.begin(); i!= TriggerRequirements.end(); i++)
	{
		(*i)->subscribeParameterChanged(entity,(*i));
	}
}

void  Trigger::setDeletedFlag(EntityControl *entity)
{

	deleted = true;

	for(std::vector<TriggerRequirement*>::iterator i = TriggerRequirements.begin(); i!= TriggerRequirements.end(); i++)
	{

		(*i)->unSubscribeParameterChanged(entity,(*i));
	}

	

}
	


bool  Trigger::getDeletedFlag()
{

	return deleted;
}

void Trigger::setAllReqDirty(bool dirty)
{
	allReqDirty = dirty;

}

std::vector<TriggerRequirement*> Trigger::getRequirements()
{
	return TriggerRequirements;
}